import lombok.Getter;

import java.io.FileOutputStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

public class Loader {
    @Getter
    private static char letters[] = {'У', 'К', 'Е', 'Н', 'Х', 'В', 'А', 'Р', 'О', 'С', 'М', 'Т'};
    @Getter
    private static String regionCode = "199";

    private static BlockingQueue<String>[] queues;

    public static void main(String[] args) throws Exception {
        System.out.println("Старый алгоритм");
        mainOld(args);

        System.out.println("Оптимизированный алгоритм - запись в один файл");
        System.out.println(executeJob(1) + " ms");

        System.out.println("Оптимизированный алгоритм - запись в 9 файлов");
        System.out.println(executeJob(9) + " ms");
    }

    private static long executeJob(int numberOfThreads) throws InterruptedException {
        long start = System.currentTimeMillis();

        queues = new BlockingQueue[numberOfThreads];

        for (int i = 0; i < numberOfThreads; i++) {
            queues[i] = new ArrayBlockingQueue<>(10);
        }

        ForkJoinPool taskPool = new ForkJoinPool((getNumberOfThreads() + 1) * 2);
        taskPool.invoke(new NumberTask(1));

        taskPool.shutdown();
        if (!taskPool.awaitTermination(10, TimeUnit.SECONDS)) {
            taskPool.shutdownNow();
        }

        return System.currentTimeMillis() - start;
    }

    public static int getNumberOfThreads() {
        return queues.length;
    }

    public static BlockingQueue<String> getQueue(int taskNumber) {
        return queues[taskNumber - 1];
    }

    public static String padNumber(int number, int numberLength) {
        char[] chars = new char[numberLength];

        for (int i = numberLength - 1; i >= 0; i--) {
            chars[i] = Character.forDigit(number % 10, 10);
            number /= 10;
        }

        return String.valueOf(chars);
    }

    // --- OLD CODE ---

    public static void mainOld(String[] args) throws Exception {
        long start = System.currentTimeMillis();

        FileOutputStream writer = new FileOutputStream("res/numbers.txt");

        for (int number = 1; number < 1000; number++) {
            int regionCode = 199;
            for (char firstLetter : letters) {
                for (char secondLetter : letters) {
                    for (char thirdLetter : letters) {
                        String carNumber = firstLetter + padNumberOld(number, 3) +
                            secondLetter + thirdLetter + padNumberOld(regionCode, 2);
                        writer.write(carNumber.getBytes());
                        writer.write('\n');
                    }
                }
            }
        }

        writer.flush();
        writer.close();

        System.out.println((System.currentTimeMillis() - start) + " ms");
    }

    private static String padNumberOld(int number, int numberLength) {
        String numberStr = Integer.toString(number);
        int padSize = numberLength - numberStr.length();

        for (int i = 0; i < padSize; i++) {
            numberStr = '0' + numberStr;
        }

        return numberStr;
    }
}
